<template>
    <input type="file" :accept="accept" ref="input" @input="onChange" class="upload-input" />
    <div class="upload-card">
        <div v-if="value" @mouseenter="() => showEdit = true" @mouseleave="() => showEdit = false">
            <div class="upload-edit" v-if="value && showEdit" @click.self="() => input?.click()">
                <ElIcon>
                    <ZoomIn @click="showPreview = true" />
                </ElIcon>
                <ElIcon style="margin-left: 16px;">
                    <Delete @click="omRemove" />
                </ElIcon>
            </div>
            <ElImage :src="value" fit="contain" style="width: 100%; height: 100%;">
            </ElImage>
        </div>
        <div v-else class="upload-icon" @click="() => input?.click()">
            <ElIcon>
                <Plus />
            </ElIcon>
        </div>
    </div>
    <ElImageViewer v-if="showPreview" :url-list="[value || '']" @close="showPreview = false" />
</template>

<script setup lang="ts">
import { ref, useTemplateRef } from "vue";
import { Delete, Plus, ZoomIn } from "@element-plus/icons-vue";
import { ElIcon, ElImage, ElImageViewer } from "element-plus";

interface prop {
    accept?: string;
    size?: string;
    value?: string;
}
interface emit {
    (e: 'change', url: string): void;
    (e: 'remove'): void;
}
const { accept = 'image/*', size = '120px' } = defineProps<prop>()
const emit = defineEmits<emit>()
const input = useTemplateRef<HTMLInputElement>('input')
const showEdit = ref(false)
const fileUrl = ref<string>('')
const showPreview = ref(false)

const onChange = (e: Event) => {
    const file = (e.target as HTMLInputElement).files?.[0]
    if (file) {
        fileUrl.value = URL.createObjectURL(file)
        emit('change', fileUrl.value)
    }
}

const omRemove = () => {
    input.value!.files = null
    emit('remove')
}
</script>
<style scoped>
.el-icon {
    cursor: pointer;
}

.el-icon:hover {
    color: var(--el-color-primary);
}

.upload-input {
    display: none;
}

.upload-card {
    position: relative;
    width: v-bind(size);
    height: v-bind(size);
    border: 1px dashed #ccc;
    border-radius: 4px;
    display: flex;
}

.upload-edit {
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    right: 0;
    background-color: rgba(0, 0, 0, 0.5);
    color: #fff;
    z-index: 99;
    display: flex;
    align-items: center;
    justify-content: center;
}

.upload-icon {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}
</style>
